﻿namespace Text2Rss.Web.Controllers
{
	#region Using directives
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Web;
	using System.Web.Mvc;
	using NHibernate;
	using Text2Rss.Web.Code;
	#endregion

	/// <summary>
	/// Base controller
	/// </summary>
	public class BaseController : Controller
	{
		#region Fields

		private ISessionFactory sessionFactory;
		
		#endregion

		#region Properties
		
		/// <summary>
		/// Gets session factory for the controller
		/// </summary>
		public ISessionFactory SessionFactory
		{
			get
			{
				return sessionFactory;
			}
		}

		#endregion // Properties

		#region Constructor
		/// <summary>
		/// .ctor
		/// </summary>
		/// <param name="sessionFactory">Sessioin factory</param>
		public BaseController(ISessionFactory sessionFactory)
		{
			this.sessionFactory = sessionFactory;
		}
		#endregion

		#region Methods

		/// <summary>
		/// Returns general JsonResult for client. By defaulst result is true, message is empty
		/// </summary>
		/// <param name="result">Result of the operation</param>
		/// <param name="message">Status message</param>
		/// <returns>Json response for client</returns>
		public JsonResult Result(bool result = true, string message = "")
		{
			return new JsonResult
			{
				Data = new
				{
					success = result,
					message = message
				}
			};
		}

		/// <summary>
		/// Returns data for client. The methods sets 'success' to true
		/// </summary>
		/// <param name="data">Data to return</param>
		/// <returns>Json response for client</returns>
		public JsonResult ResultData(object data)
		{
			return new JsonResult
			{
				Data = new
				{
					success = true,
					data = data,
					message = string.Empty
				}
			};
		}

		/// <summary>
		/// Wraps the function with try/catch block.
		/// </summary>
		/// <param name="func">Function to wrap</param>
		/// <returns>Either Json response from the function or error respose with error message</returns>
		public JsonResult WrapWithTryCatch(Func<ISession, JsonResult> func)
		{
			try
			{
				using (ISession session = SessionFactory.OpenSession())
				{
					return func(session);
				}
			}
			catch (Exception ex)
			{
				Log.Logger.Error("WrapWithTryCatch", ex);
				return Result(false, ex.Message);
			}
		}

		/// <summary>
		/// Executes the function in a transaction
		/// </summary>
		/// <param name="func">Function to execute</param>
		/// <returns>Either Json response from the function or error respose with error message</returns>
		public JsonResult WrapWithTran(Func<ISession, JsonResult> func)
		{
			return WrapWithTryCatch((session) =>
			{
				using (var tran = session.BeginTransaction())
				{
					try
					{
						JsonResult result = func(session);
						tran.Commit();
						return result;
					}
					catch (Exception)
					{
						tran.Rollback();
						throw;
					}
				}
			});
		}

		#endregion // Methods
	}
}
